package cn.foolishbird.crow.mybatis.plus.handlers;

import cn.foolishbird.crow.enumeration.WhetherEnum;
import cn.foolishbird.crow.mybatis.plus.CrowEntityFieldEnum;
import org.apache.ibatis.reflection.MetaObject;

import java.util.Objects;

/**
 * mybatisplus 增强类
 *
 * @param <ID>
 */
public abstract class CrowMetaObjectHandler<T, ID> extends ClzMatchMetaObjectHandler<T> {

    /**
     * 主键类型class
     */
    private final Class<ID> idClz;

    public CrowMetaObjectHandler(Class<T> clz, Class<ID> idClz) {
        super(clz);
        this.idClz = idClz;
    }

    /**
     * mysql插入sql，执行的通用逻辑
     *
     * @param metaObject 元数据对象
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        long create = System.currentTimeMillis();
        this.strictInsertFill(metaObject, CrowEntityFieldEnum.CREATE_TIME.getFieldName(), Long.class, create);
        this.strictInsertFill(metaObject, CrowEntityFieldEnum.UPDATE_TIME.getFieldName(), Long.class, create);
        this.strictInsertFill(metaObject, CrowEntityFieldEnum.DEL_FLAG.getFieldName(), Integer.class,
                WhetherEnum.NO.value());

        ID operateUserId = operateUserId();
        if (Objects.nonNull(operateUserId)) {
            this.strictInsertFill(metaObject, CrowEntityFieldEnum.CREATE_BY.getFieldName(), this.idClz, operateUserId);
            this.strictInsertFill(metaObject, CrowEntityFieldEnum.UPDATE_BY.getFieldName(), this.idClz, operateUserId);
        }
    }

    /**
     * mysql执行update的时候，执行的通用逻辑
     *
     * @param metaObject 元数据对象
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, CrowEntityFieldEnum.UPDATE_TIME.getFieldName(), Long.class,
                System.currentTimeMillis());
        // 获取操作人信息
        ID operateUserId = operateUserId();
        if (Objects.nonNull(operateUserId)) {
            this.strictInsertFill(metaObject, CrowEntityFieldEnum.UPDATE_BY.getFieldName(), this.idClz, operateUserId);
        }
    }

    /**
     * 获取操作人信息
     *
     * @return 操作人信息
     */
    protected abstract ID operateUserId();
}
